<?php /**
*Abstract Collection class holds objects and provides iterator methods.
*Uses the Iterator and ArrayAccess interfaces to provide maximum flexibility
*@package Commands
*@author Garry Willits && Matt Zandstra
*@copyright 2005
*@version 1.1
*/

Abstract Class Collection implements Iterator, ArrayAccess{
/**
*@var array holds objects in collection
*/
protected $collection=array();
/**
*@var int
*/
protected $pointer=0;
/**
*You must define a public constructor method in concrete sub types that checks that object is type safe
*@param object add to collection
*/
protected function __construct( $object=null ){
if( isset( $object) ){
$this->doAddElement( $object );
}

}
/**
*You must define a public accessor method in concrete subtypes that checks that object is type safe
*@param object add to collection
*/
protected function doAddElement($object){
$this->collection[]=$object;
}
/**
*You must define a public accessor method in concrete subtypes that checks that object is type safe
*@param object add to collection
*@param int key
*/
protected function doAddElementByKey( $object, $key ){
$this->collection[$key]=$object;
}
/**
*Remove object from collection
*/
public function RemoveElement( $object ){
$ctr=0;
    foreach( $this->collection as $key => $val ){
        if( $val === $object ){
        unset( $this->collection[ $ctr]);
      }
      $ctr++;
    }

}
public function contains( $object ){

    if( is_array( $this->collection )){
        foreach( $this->collection as $check ){
            if( $check === $object){
            return $object;
            }
    }
}
return false;
}
// Iterator Methods
/**
*Rewind pointer back to begining
*@return bool
*/
public function rewind(){
$this->pointer=0;
}
/**
*Returns current object
*@return object current object that pointer references
*/
public function current(){
	if( array_key_exists($this->pointer,$this->collection)){
		return $this->collection[ $this->pointer ];
	}
	else {
		return FALSE;
	}
}
/**
*returns pointer
*@return int pointer references
*/
public function key(){
return $this->pointer;
}
/**
*get next object if it exists otherwise throw exception
*@return object next object
*/
public function next(){
$retobj = $this->collection[ $this->pointer ];
    if( $retobj ){
    $this->pointer++;
    return $retobj;
    }
    else {
    throw new Exception("you must check with valid() function to see if further data    exists. This exception should not occur");
    }
}
/**
*Check to see if current pointer is valid
*@return bool
*/
public function valid(){
	$valid = $this->current();
	if( !$valid ){
		return false;
	}
	return true;
}
// ArrayAccess Methods
/**
*Integer based array access
*@return object
*/
public function offsetGet( $number ){
return $this->collection[ $number ];
}
/**
*Checks to see if this element exists
*@return bool
*/
public function offsetExists( $key ){

$valid = $this->collection[ $key ];
return isset( $valid );
}
/**
*Insert value into array. Will only accept numeric keys and objects of correct type
*@return object
*/
public function offsetSet( $key, $object ){
if( !is_numeric($key) ){
return false;
}
$this->addElement($object,$key);
}
/**
*Remove object from collection
*/
public function offsetUnset( $key ){
unset( $this->collection[ $key ]);
}
/**
 * useful
 * Enter description here ...
 */
public function size(){
	return count( $this->collection );
}

public function __toString(){
	return print_r( $this->collection,TRUE);
}
}

?>
